package com.taomus.mytools.lang.utils.asm;

import java.util.HashMap;

import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.GeneratorAdapter;
import org.objectweb.asm.commons.Method;
import org.objectweb.asm.util.TraceClassVisitor;

import com.taomus.mytools.lang.utils.CommonUtils;

public class CreateClass extends CreateFunction {

	
	GeneratorAdapter ga = null;

	public CreateClass(TraceClassVisitor tcvisitor, String name) {
		this.tcvisitor = tcvisitor;
		this.createConstructor(name);
		this.className = name;
	}

	private void createConstructor(String name) {
		this.createConstructor(name,"java/lang/Object",null);
	}
	
	private void createConstructor(String name,String superName,String[] interfaces) {
		this.fieldVeriable = new HashMap<>();
		tcvisitor.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC, name, null, superName, interfaces);
		Method m = Method.getMethod("void <init>()");
		GeneratorAdapter ga = new GeneratorAdapter(Opcodes.ACC_PUBLIC, m, null, null, tcvisitor);
		ga.loadThis();
		ga.invokeConstructor(Type.getType(Object.class), m);
		ga.returnValue();
		ga.endMethod();
	}
	
	public void createPrivateField(String name,Class<?> zlass) {
		tcvisitor.visitField(Opcodes.ACC_PRIVATE, name, Type.getType(zlass).getDescriptor(),null, null).visitEnd();
		this.fieldVeriable.put(name, zlass);
		String fName = CommonUtils.camelUpperName(name);
		GeneratorAdapter ga = new GeneratorAdapter(Opcodes.ACC_PUBLIC,Method.getMethod(zlass.getSimpleName()+" get"+fName+"()"),null,null,tcvisitor);
		ga.loadThis();
		ga.getField(Type.getType(this.className), name, Type.getType(zlass));
		ga.returnValue();
		ga.endMethod();
		ga = new GeneratorAdapter(Opcodes.ACC_PUBLIC,Method.getMethod("void set"+fName+"("+zlass.getSimpleName()+")"),null,null,tcvisitor);
		ga.loadThis();
		ga.loadArg(0);
		ga.putField(Type.getType(this.className), name, Type.getType(zlass));
		ga.returnValue();
		ga.endMethod();
	}
	
	public void createPublieField(String name,Class<?> zlass) {
		tcvisitor.visitField(Opcodes.ACC_PUBLIC, name, Type.getType(zlass).getDescriptor(),null, null).visitEnd();
		this.fieldVeriable.put(name, zlass);
	}
	
	public void createProtectedField(String name,Class<?> zlass) {
		tcvisitor.visitField(Opcodes.ACC_PROTECTED, name, Type.getType(zlass).getDescriptor(),null, null).visitEnd();
		this.fieldVeriable.put(name, zlass);
	}

}
